import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test {
    public static int cnt = 0;
    public static void main(String[] args) throws InterruptedException {
        Object obj = new Object();
        Thread t1 = new Thread(() -> {
            synchronized (obj){
                for (int i = 0; i < 5000; i++) {
                    cnt++;
                }
            }
        });
        Thread t2 = new Thread(() -> {
            synchronized (obj){
                for (int i = 0; i < 5000; i++) {
                    cnt++;
                }
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(cnt);
    }
}
class Solution {
    public long repairCars(int[] ranks, int cars) {
        long l = 0, r = (long)ranks[0]*cars*cars;
        while(l <= r){
            long mid = (l+r)>>1;
            long s = 0;
            for(int x : ranks){
                s += Math.sqrt(mid/x);
            }
            if(s >= cars){
                r = mid-1;
            }else{
                l = mid+1;
            }
        }
        return r+1;
    }
}
class Solution1 {
    public int[] minOperationsQueries(int n, int[][] edges, int[][] queries) {
        List<int[]>[] g = new ArrayList[n];
        Arrays.setAll(g,e -> new ArrayList<>());
        for(var e : edges){
            int x = e[0], y = e[1], w = e[2]-1;
            g[x].add(new int[]{y,w});
            g[y].add(new int[]{x,w});
        }//记录每一个节点的相邻节点及权重

        int m = 32 - Integer.numberOfLeadingZeros(n);
        var pa = new int[n][m];
        //n:节点，m：向上走2^m步, pa[i][j]:到达哪个节点
        for(int i=0; i<n; i++){
            Arrays.fill(pa[i],-1);
        }
        var cnt = new int[n][m][26];
        //从n向上走 2^m步 过程中 每个权重的个数
        var depth = new int[n];//每个节点的深度
        dfs(0,-1,g,pa,cnt,depth);

        //树上倍增
        for(int i=0; i<m-1; i++){
            for(int x = 0; x < n; x++){
                int p = pa[x][i];
                if(p != -1){
                    int pp = pa[p][i];
                    pa[x][i+1] = pp;
                    for(int j = 0; j < 26; j++){
                        cnt[x][i+1][j] = cnt[x][i][j] + cnt[p][i][j];
                    }
                }
            }
        }

        //交换
        var ans = new int[queries.length];
        for(int qi = 0; qi < queries.length; qi++){
            int x = queries[qi][0], y = queries[qi][1];
            int pathLen = depth[x] + depth[y];
            var cw = new int[26];//统计不同权重的个数
            if(depth[x] > depth[y]){
                int tmp = x;
                x = y;
                y = tmp;
            }
            //让y向上走,使得x,y节点的深度一样
            for(int k = depth[y]-depth[x]; k > 0; k &= k-1){
                int i = Integer.numberOfTrailingZeros(k);
                int p = pa[y][i];//j向上走2^i步
                for(int j=0; j<26; j++){
                    cw[j] += cnt[y][i][j];//统计y向上走的过程中的权重
                }
                y = p;//y节点走到p节点位置
            }

            if(y != x){//x,y同时向上走,找到相遇点
                for(int i=m-1; i>=0; i--){
                    int px = pa[x][i];//从x节点向上走2^i步
                    int py = pa[y][i];//从y节点向上走2^i步
                    if(px != py){
                        for(int j=0; j<26; j++){
                            cw[j] += cnt[x][i][j]+cnt[y][i][j];//统计x,y向上走的过程中的权重
                        }
                        x = px;//更新x的位置
                        y = py;//更新x的位置
                    }
                }
                for(int j = 0; j < 26; j++){
                    cw[j] += cnt[x][0][j] + cnt[y][0][j];//统计x,y向上走的过程中，不同权重的个数
                }
                x = pa[x][0];//注意要在往上走一步才是相遇点
            }

            int lca = x;
            pathLen -= depth[lca]*2;//真正的路径长度
            int maxCw = 0;//求出现次数最多的权重
            for(int i=0; i<26; i++){
                maxCw = Math.max(maxCw,cw[i]);
            }
            ans[qi] = pathLen - maxCw;//路径长度-权重出现最多次数=操作最少
        }
        return ans;
    }

    private void dfs(int x, int fa, List<int[]>[] g, int[][] pa, int[][][] cnt, int[] depth) {
        pa[x][0] = fa;//初始化
        for (var e : g[x]) {//遍历x节点可以走向那些节点
            int y = e[0], w = e[1];
            //y：x走向的那些节点，w:从x节点到y节点的权重
            if (y != fa) {//不能重复计算 比如：i->j j->i
                cnt[y][0][w] = 1;//初始化每个节点向周围走一步的权重
                depth[y] = depth[x] + 1;//初始化每个节点的深度
                dfs(y, x, g, pa, cnt, depth);
            }
        }
    }
}